package weaver.aiyh_quanshi;

import aiyh.utils.zwl.common.ToolUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import weaver.aiyh_quanshi.entity.QsConfParty;
import weaver.aiyh_quanshi.entity.QsConfSetting;
import weaver.aiyh_quanshi.entity.QsResponse;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class QsAPI {

	private static boolean initialized = false;
	private static final ToolUtil logger = new ToolUtil();

	private static final String KEY_STORE_TYPE_JKS = "jks";
	private static final String KEY_STORE_TYPE_P12 = "PKCS12";
	private static final String SCHEME_HTTPS = "https";
	private static final int HTTPS_PORT = 443;

	private static final String KEY_STORE_PASSWORD = "111111";
	private static final String KEY_STORE_TRUST_PASSWORD = "111111";

	static SSLContext sslContext = null;
	static HttpClient httpClient = new DefaultHttpClient();

	private static Integer appId = 6;
	private static String productId = "";
	private static String siteUrl = "";

	/**
	 * 初始化
	 */
	public static void init(String _appId, String _siteUrl, String _p12Path, String _trustPath) {
//		logger.writeErrorLog("Init is beginning!");
		try {
			appId = Integer.parseInt(_appId);
			siteUrl = _siteUrl;
			if (appId == 2) {
				productId = "20000";
			} else if (appId == 5) {
				productId = "50000";
			} else if (appId == 3) {
				productId = "30000";
			} else if (appId == 4) {
				productId = "40000";
			} else if (appId == 6) {
				productId = "60000";
			}

			System.setProperty("javax.net.ssl.keyStore", _p12Path);
			System.setProperty("javax.net.ssl.keyStorePassword", KEY_STORE_PASSWORD);
			System.setProperty("javax.net.ssl.keyStoreType", KEY_STORE_TYPE_P12);
			System.setProperty("javax.net.ssl.trustStore", _trustPath);
			System.setProperty("javax.net.ssl.trustStorePassword", KEY_STORE_TRUST_PASSWORD);
			System.setProperty("javax.net.ssl.trustStoreType", KEY_STORE_TYPE_JKS);

			KeyStore kstore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
			kstore.load(new FileInputStream(_p12Path), KEY_STORE_PASSWORD.toCharArray());
			//sunx509, IbmX509
			KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("sunx509");
			keyFactory.init(kstore, KEY_STORE_PASSWORD.toCharArray());
			KeyStore tstore = KeyStore.getInstance(KEY_STORE_TYPE_JKS);
			tstore.load(new FileInputStream(_trustPath), KEY_STORE_TRUST_PASSWORD.toCharArray());

			TrustManager[] tm;
			// sunx509
			TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
			tmf.init(tstore);
			tm = tmf.getTrustManagers();

			sslContext = SSLContext.getInstance("SSL");
			sslContext.init(keyFactory.getKeyManagers(), tm, null);

			initialized = true;
//			logger.writeErrorLog("Init is success!");
		} catch (Exception e) {
			logger.writeErrorLog(e.getMessage(), e.toString());
			logger.writeErrorLog("Init error:please check cert path is set correctly");
		}
	}

	/**
	 * 创建预约会议
	 *
	 * @param email       创建人邮箱
	 * @param confTitle   会议标题
	 * @param confLen     会议时长，分钟为单位
	 * @param startTime   会议开始时间
	 * @param setting     会议设置
	 * @param inviteeList 参会人员列表
	 * @return
	 */
	public static QsResponse reservConference(String email, String confTitle, int confLen, String startTime, QsConfSetting setting, List<QsConfParty> inviteeList) {
		String URL = "https://openapi.quanshi.com/conference/conference/reservConference";
		if (!initialized) {
			return genError(QsErrorCode.CERT_ERROR);
		} else {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("appId", appId);
			param.put("title", confTitle);
			param.put("length", confLen);
			param.put("starttime", startTime);
			param.put("from", "OA");
//			param.put("userId", userId);
			param.put("email", email);
			param.put("inviteeList", inviteeList);
			if (setting != null) {
				Map<String, Object> settingMap = new HashMap<String, Object>();
				if (setting.isShowInfo() != null) {
					settingMap.put("isShowInfo", setting.isShowInfo() ? 1 : 0);
				}
				if (setting.isAllowUnmute() != null) {
					settingMap.put("isAllowUnmute", setting.isAllowUnmute() ? 1 : 0);
				}
//			    settingMap.put("isShowVideo", setting.isShowVideo()!=null&&setting.isShowVideo() ? 1 : 0);  不用了
				if (setting.isOnly() != null) {
					settingMap.put("isOnly", setting.isOnly() ? 1 : 0);
				}
				param.put("seting", settingMap);
				if (setting.isSmsNotify() != null) {
					param.put("sms_notify", setting.isSmsNotify());
				}
				if (setting.isEmailNotify() != null) {
					param.put("email_notify", setting.isEmailNotify());
				}
				if (setting.getPasscodeType() != null) {
					param.put("password_type", setting.getPasscodeType());
				}
				if (setting.getAutoRecord() != null) {
					param.put("autoRecord", setting.getAutoRecord());
				}
				if (setting.getConfLevelMute() != null) {
					param.put("confLevelMute", setting.getConfLevelMute());
				}
				if (setting.getMustSelectAudio() != null) {
					param.put("mustSelectAudio", setting.getMustSelectAudio());
				}
				if (setting.getExtend() != null) {
					param.put("extend", setting.getExtend());
				}
			}
			String result = httpPost(URL, QsUtil.jsonOTS(param));
			return parseResult(QsUtil.jsonSTM(result));
		}
	}


	/**
	 * 取消预约会议(参考接口文档3.3章节)
	 *
	 * @param conferenceId 会议ID
	 * @param email        会议主持人邮件
	 * @return 服务器返回的JSON
	 */
	public static QsResponse cancelConference(String conferenceId, String email, Boolean emailNotify, Boolean smsNotify) {
		String URL = "https://openapi.quanshi.com/conference/conference/cancelReservConference";
		if (!initialized) {
			return genError(QsErrorCode.CERT_ERROR);
		} else {
			String url = URL + "/" + appId + "/" + conferenceId + "/zh-CN/" + email;
			if (emailNotify != null && smsNotify != null) {
				url += "//" + emailNotify + "/" + smsNotify;
			}
			String result = httpGet(url);
			return parseResult(QsUtil.jsonSTM(result));
		}
	}


	/**
	 * 取消预约会议(参考接口文档3.3章节)
	 *
	 * @param conferenceId 会议ID
	 * @param userId       会议主持人ID
	 * @return 服务器返回的JSON
	 */
	public static QsResponse cancelConference(String conferenceId, Integer userId, Boolean emailNotify, Boolean smsNotify) {
		String URL = "https://openapi.quanshi.com/conference/conference/cancelReservConference";
		if (!initialized) {
			return genError(QsErrorCode.CERT_ERROR);
		} else {
			String url = URL + "/" + appId + "/" + conferenceId + "/zh-CN/" + userId;
			if (emailNotify != null && smsNotify != null) {
				url += "//" + emailNotify + "/" + smsNotify;
			}
			String result = httpGet(url);
			return parseResult(QsUtil.jsonSTM(result));
		}
	}

	/**
	 * 通过邮箱查询账号信息
	 * @param emails 电子邮箱数组
	 * @return 服务器返回的JSON
	 */
	public static QsResponse getUserIdsByEmails(List<String> emails) {
		String URL = "https://openapi.quanshi.com/confopenapi/account/getUsersByEmailsMobiles";
		if (!initialized) {
			return genError(QsErrorCode.CERT_ERROR);
		}
		else {
			Map<String, Object> param = new HashMap<String, Object>();
//			param.put("appId", appId);
//			param.put("appKey", appKey);
			param.put("emails", emails);
			String result = httpPost(URL, QsUtil.jsonOTS(param));
			return parseResult(QsUtil.jsonSTM(result));
		}
	}


	/**
	 * 获取预约会议基本信息(参考接口文档3.5章节)
	 *
	 * @param conferenceId 会议ID
	 * @return 服务器返回的JSON
	 */
	public static QsResponse getConferenceInfo(String conferenceId) {
		String URL = "https://openapi.quanshi.com/conference/conference/getConferenceBaseInfoById/6/";
		if (!initialized) {
			return genError(QsErrorCode.CERT_ERROR);
		} else {
			String result = httpGet(URL + conferenceId);
			return parseResult(QsUtil.jsonSTM(result));
		}
	}

	/**
	 * 解析返回值
	 *
	 * @param resultMap
	 * @return
	 */
	private static QsResponse parseResult(Map<String, Object> resultMap) {
		QsResponse response = new QsResponse();
		if (resultMap != null && resultMap.containsKey("status")) {
			String status = String.valueOf(resultMap.get("status"));
			response.setStatus(status);
			response.setReqid(String.valueOf(resultMap.get("reqid")));
			response.setResult(String.valueOf(resultMap.get("result")));
		}
		return response;
	}

	/**
	 * 返回错误码
	 *
	 * @param errorCode 错误代码
	 * @return JSON格式错误字符串
	 */
	private static QsResponse genError(String errorCode) {
		Map<String, Object> errorMap = new HashMap<String, Object>();
		errorMap.put("status", QsErrorCode.CERT_ERROR);
		if (errorCode.equals(QsErrorCode.CERT_ERROR)) {
			errorMap.put("desc", "please initialized API, check cert path!");
		}
		errorMap.put("result", null);
		return parseResult(errorMap);
	}


	/**
	 * Get方式请求
	 *
	 * @param url 请求地址
	 * @return 请求Response
	 */
	public static String httpGet(String url) {
		try {
			SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
			Scheme sch = new Scheme(SCHEME_HTTPS, HTTPS_PORT, socketFactory);
			httpClient.getConnectionManager().getSchemeRegistry().register(sch);
			HttpGet httpGet = new HttpGet(url);
			httpGet.addHeader("Content-Type", "application/json");
			httpGet.addHeader("charset", HTTP.UTF_8);

//			logger.writeErrorLog("executing request " + httpGet.getRequestLine());

			HttpResponse response = httpClient.execute(httpGet);

			HttpEntity entity = response.getEntity();
			if (entity != null) {
				String result = EntityUtils.toString(entity, "utf-8");
//				System.out.println(result);
//				logger.writeErrorLog("Response content length: " + result;
//				logger.writeErrorLog("Response content: " + result);
/*				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
				String text;
				StringBuffer buf = new StringBuffer();
				while ((text = bufferedReader.readLine()) != null) {
					buf.append(text);
				}
				bufferedReader.close();*/
				return result;
			}
			EntityUtils.consume(entity);
		} catch (Exception e) {
			logger.writeErrorLog(e.getMessage(), e.toString());
		}
		return "{}";
	}

	/**
	 * Post方式请求
	 *
	 * @param url       请求地址
	 * @param jsonParam 请求参数
	 * @return 请求Response
	 */
	public static String httpPost(String url, String jsonParam) {
		try {
			httpClient = new DefaultHttpClient();
			SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext);
			Scheme sch = new Scheme(SCHEME_HTTPS, HTTPS_PORT, socketFactory);
			httpClient.getConnectionManager().getSchemeRegistry().register(sch);
			HttpPost httpPost = new HttpPost(url);
			httpPost.addHeader("Content-Type", "application/json; charset=utf-8");
			httpPost.setHeader("Accept", "application/json");
			httpPost.addHeader("charset", HTTP.UTF_8);
			httpPost.setEntity(new StringEntity(jsonParam.toString(), HTTP.UTF_8));

//			logger.writeErrorLog("executing request " + httpPost.getRequestLine());
//			logger.writeErrorLog("executing params " + jsonParam.toString());
			HttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
//            	EntityUtils.consume(entity);
				String result = EntityUtils.toString(entity, "utf-8");
//				logger.writeErrorLog("Response content is : " + result);
//                BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(entity.getContent())); 
//                String text;
//                StringBuffer buf = new StringBuffer();
//                while ((text = bufferedReader.readLine()) != null ) {
//                	buf.append(text);
//                }
//                bufferedReader.close();
//                return buf.toString();
				return result;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.writeErrorLog(e.getMessage(), e.toString());
		}
		return "";
	}

	static class QsErrorCode {
		/**
		 * 客户端证书未配置
		 **/
		public static final String CERT_ERROR = "50100";

	}
}
